package com.dbq.fast.business.main.model;

import android.util.Log;

import com.dbq.fast.App;
import com.dbq.fast.business.login.api.LoginApi;
import com.dbq.fast.business.main.bean.VpnNode;
import com.dbq.fast.business.product.api.CommonTransformer;
import com.dbq.fast.common.bean.User;
import com.dbq.fast.common.json.GsonT;
import com.dbq.fast.common.net.HttpManager;
import com.dbq.fast.common.net.HttpResult;
import com.dbq.fast.common.net.RemoteApiCallBack;
import com.dbq.fast.util.SystemUtil;
import com.dbq.fast.util.TimeOutHandler;
import com.yiba.vpn.utils.Constants;
import com.yiba.vpn.utils.RxBus;
import com.yiba.vpn.utils.logger.LogUtil;

import java.util.concurrent.atomic.AtomicInteger;

import retrofit2.Response;


/**
 * Created by sunkai on 2017/10/30.
 */

public class VpnModel {

    static AtomicInteger mark;
    HttpManager httpManager = HttpManager.getInstance();

    public VpnNode getPackageInfo(String token, String account) {
        try {
            Response<HttpResult<VpnNode>> response = httpManager.getHttpService().querySetMeal(111, SystemUtil.getLanguageCustom(App.getContext()), token, account, 2).execute();
            HttpResult<VpnNode> httpResult = response.body();
            if (httpResult == null) {
                LogUtil.e("get vpnNode net err,http code:" + response.code() + ",msg:" + response.errorBody().toString());
                return null;
            }

            int code = httpResult.getCode();
            if (code == 200 || code == -1005) {
                LogUtil.e("vpnNode ,config:" + httpResult.getData().toString());
                return httpResult.getData();
            } else {
                LogUtil.e("get vpnNode err,code:" + httpResult.getCode() + ",msg:" + httpResult.getMsg());
                if (code == 401) {
                    String newToken = LoginApi.refreshTokenSync(true);
                    if ("".equals(newToken)) return null;
                    return getPackageInfo(newToken, account);
                } else if (code == 402) {
                    RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_OTHER_DEVICE_LOGIN);
                    return null;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public VpnNode getVpnConfig(String token, String account) {
        if (mark == null) {
            mark = new AtomicInteger(0); //0：开始网络请求，1：网络请求结束，2：网络超时
        } else {
            mark.set(0);
        }
        TimeOutHandler timeOutHandler = new TimeOutHandler();
        timeOutHandler.setTimeOutListener(() -> {
            if (mark.get() == 1) return;
            mark.set(2);
            RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_GET_VPN_TIME_OUT);
        });
        timeOutHandler.startTiming();

        try {
            Response<HttpResult<VpnNode>> response = httpManager.getHttpService().getVpnConfig(111, SystemUtil.getLanguageCustom(App.getContext()), token, account, 2, false).execute();
            if (mark.get() == 2) return null;
            mark.set(1);
            HttpResult<VpnNode> httpResult = response.body();
            if (httpResult == null) {
                LogUtil.e("get vpnNode net err,http code:" + response.code() + ",msg:" + response.errorBody().toString());
            } else {
                int code = httpResult.getCode();
                if (code == 200) {
                    LogUtil.e("vpnNode ,config:" + httpResult.getData().toString());
                    return httpResult.getData();
                } else {
                    LogUtil.e("get vpnNode err,code:" + httpResult.getCode() + ",msg:" + httpResult.getMsg());
                    if (code == 401) {
                        if (!User.getInstance().isLogin()) return null;
                        String newToken = LoginApi.refreshTokenSync(true);
                        if ("".equals(newToken)) return null;
                        return getVpnConfig(newToken, account);
                    } else if (code == 402) {
                        RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_OTHER_DEVICE_LOGIN);
                        return null;
                    } else if (code == -1004) {
                        RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_NO_SERVICE);
                    } else if (code == -1005) {
                        RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_SERVICE_OUT_DATE);
                    } else if (code == -1007) {
                        RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_CREATE_NODE_EXCEPTION);
                    } else {
                        RxBus.get().post(Constants.RXBUS_START_VPN, Constants.RXBUS_LOAD_VPN_ERROR);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void getProxyDomain() {
        HttpManager.getInstance().getHttpService()
                .getProxyDomain(User.getInstance().getToken())
                .compose(new CommonTransformer<>())
                .subscribe(httpResult -> {

                    if (httpResult.getCode() == 200) {
                        if (!httpResult.getData().proxy_domain.isEmpty()) {
                            new Thread(() -> App.cache.saveCache("proxyDomain", GsonT.toJson(httpResult.getData()))).start();
                        }
                    } else if (httpResult.getCode() == 401) {
                        LoginApi.refreshToken(false, new RemoteApiCallBack<Boolean>() {
                            @Override
                            public void onSuccess(Boolean aBoolean) {
                                getProxyDomain();
                            }

                            @Override
                            public void onFail(int status, String message) {
                            }
                        });
                    } else {
                        //TODO 处理非200的情况
                    }
                }, throwable -> {
                    Log.i("test", throwable.toString());
                });

    }
}
